/*
 *	Perlin Production Co. Ltd. September 2012 (c).
 *			rgblib.c
 *		
 */

#include "WinGDI.h"
			
#define _DEBUG	0
						
RGB* InitRGB(_rgb,_r,_g,_b)
RGB*	_rgb;
char	_r;
char	_g;
char	_b;
{
	_rgb->rgbBlue		= _b;
	_rgb->rgbGreen		= _g;
	_rgb->rgbRed		= _r;
/*	
	_rgb->rgbReserved	= Lumo(_rgb);
*/	
	return _rgb;
}


RGB* CpyRGB(_dst,_src)
RGB*	_dst;
RGB*	_src;
{
	_dst->rgbBlue		= _src->rgbBlue;
	_dst->rgbGreen		= _src->rgbGreen;
	_dst->rgbRed		= _src->rgbRed;
/*	
	_dst->rgbReserved	= _src->rgbReserved;
*/	
	return _dst;
}


int	CPIRGB(_rgb, _i)
RGB*	_rgb;
int	_i;
{
	return  (	_rgb->rgbBlue	== _i
		&&	_rgb->rgbGreen	== _i
		&&	_rgb->rgbRed	== _i
		);
}




char	ClrSHL(_component) /* color component up */
char	_component;
{
	return (_component == 0xFF) ? _component : _component << 1;
}


RGB*	SHLRGB(_rgb)
RGB*	_rgb;
{
	_rgb->rgbBlue	= ClrSHL(_rgb->rgbBlue);
	_rgb->rgbGreen	= ClrSHL(_rgb->rgbGreen);
	_rgb->rgbRed	= ClrSHL(_rgb->rgbRed);
}



char	CBound(_component)
int	_component;
{
	if (_component < 0)	return 0;
	if (_component > 0xFF)	return 0xFF;
	return _component;
}



RGB* MulRGB(_rgb, _gain)
RGB*		_rgb;
unsigned	_gain;
{
	_rgb->rgbBlue  = CBound(_gain * _rgb->rgbBlue);
	_rgb->rgbGreen = CBound(_gain * _rgb->rgbGreen);
	_rgb->rgbRed   = CBound(_gain * _rgb->rgbRed);
	return _rgb;
}



RGB* AddRGB(_rgb, _gain)
RGB*	_rgb;
int	_gain;
{
	if (_rgb->rgbBlue)  _rgb->rgbBlue  = CBound(_gain + _rgb->rgbBlue);
	if (_rgb->rgbGreen) _rgb->rgbGreen = CBound(_gain + _rgb->rgbGreen);
	if (_rgb->rgbRed)   _rgb->rgbRed   = CBound(_gain + _rgb->rgbRed);
	return _rgb;
}



RGB* InrRGB(_rgb)
RGB*	_rgb;
{
	unsigned c;
	
	c = min(min(_rgb->rgbBlue, _rgb->rgbGreen),_rgb->rgbRed);
	
#if _DEBUG	
	PutRGB(_rgb,"InrRGB");
	printf("min component=%d\n",c);
#endif	
	
	if (!c) c = 1;
	
	_rgb->rgbBlue	= CBound(_rgb->rgbBlue	+ _rgb->rgbBlue  / c);
	_rgb->rgbGreen	= CBound(_rgb->rgbGreen	+ _rgb->rgbGreen / c);
	_rgb->rgbRed	= CBound(_rgb->rgbRed	+ _rgb->rgbRed   / c);
	
#if _DEBUG	
	PutRGB(_rgb,"InrRGB AFTER");
#endif
	return _rgb;
}	
	



RGB* DcrRGB(_rgb)
RGB*	_rgb;
{
	unsigned c;
	
	c = min(min(_rgb->rgbBlue, _rgb->rgbGreen),_rgb->rgbRed);
	
#if _DEBUG	
	PutRGB(_rgb,"DcrRGB");
	printf("min component=%d\n",c);
#endif
	
	if (!c) c = 1;
	
	_rgb->rgbBlue	= CBound(_rgb->rgbBlue	- _rgb->rgbBlue  / c);
	_rgb->rgbGreen	= CBound(_rgb->rgbGreen	- _rgb->rgbGreen / c);
	_rgb->rgbRed	= CBound(_rgb->rgbRed	- _rgb->rgbRed   / c);
	
#if _DEBUG	
	PutRGB(_rgb,"DcrRGB AFTER");
#endif
	return _rgb;
}	



int	IsERGB(_rgb1,_rgb2)
RGB*	_rgb1;
RGB*	_rgb2;
{
	return	(_rgb1->rgbBlue  == _rgb2->rgbBlue)
	&&	(_rgb1->rgbGreen == _rgb2->rgbGreen)
	&&	(_rgb1->rgbRed   == _rgb2->rgbRed);
}	


		
PutRGB(_rgb, _text)
RGB	*_rgb;
char	*_text;
{
	printf("%s [b:%03u, g:%03u, r:%03u]\n"	, Ptr2Str(_text,0)
						, _rgb->rgbBlue
						, _rgb->rgbGreen
						, _rgb->rgbRed
						);
}


/* Calculates rgb luminosity, based on weights */

unsigned Lumo(_rgb)
RGB	*_rgb;
{
	return	(_rgb->rgbBlue  + _rgb->rgbGreen + _rgb->rgbRed) / 3;
}



char	Clr233(_rgb888)
RGB*	_rgb888;
{
	unsigned	r,g,b;
	
	b = _rgb888->rgbBlue  >> 6;
	g = _rgb888->rgbGreen >> 5;
	r = _rgb888->rgbRed   >> 5;
	
	return (b << 6)	+ (g << 3) + r;
};	



/* Scale from true color to Vector color space */
/* BGR(8,8,8) to BGR(2,3,3) */
/* Convert RGB to 233, return color index in 233 color space */

char RGB233(_rgb)
RGB*	_rgb;
{
	_rgb->rgbBlue  >>= 6;
	_rgb->rgbGreen >>= 5;
	_rgb->rgbRed   >>= 5;
	
	return _rgb->rgbReserved= (_rgb->rgbBlue << 6)
				+ (_rgb->rgbGreen << 3)
				+ _rgb->rgbRed;
};	


#if 0
/* BGR(2,3,3) to BGR(8,8,8) */
	
char RGB888(_rgb)
RGB*	_rgb;
{
	_rgb->rgbBlue	*= 0x55;
	_rgb->rgbGreen	= ((_rgb->rgbGreen >= 7) ? 0xFF : _rgb->rgbGreen * 36);
	_rgb->rgbRed	= ((_rgb->rgbRed >= 7) ? 0xFF : _rgb->rgbRed * 36);
}
#endif	
